class MyPromise {
    constructor(executor) {
      this.status = 'pending';
      this.value = undefined;
      this.reason = undefined;
      this.onResolvedCallbacks = [];
      this.onRejectedCallbacks = [];
  
      const resolve = (value) => {
        if (this.status === 'pending') {
          this.status = 'resolved';
          this.value = value;
          this.onResolvedCallbacks.forEach((fn) => fn());
        }
      };
  
      const reject = (reason) => {
        if (this.status === 'pending') {
          this.status = 'rejected';
          this.reason = reason;
          this.onRejectedCallbacks.forEach((fn) => fn());
        }
      };
  
      try {
        executor(resolve, reject);
      } catch (error) {
        reject(error);
      }
    }
  
    then(onResolved, onRejected) {
      onResolved = typeof onResolved === 'function' ? onResolved : (value) => value;
      onRejected = typeof onRejected === 'function' ? onRejected : (reason) => { throw reason; };
  
      const promise2 = new MyPromise((resolve, reject) => {
        if (this.status === 'resolved') {
          setTimeout(() => {
            try {
              const x = onResolved(this.value);
              resolvePromise(promise2, x, resolve, reject);
            } catch (error) {
              reject(error);
            }
          }, 0);
        } else if (this.status === 'rejected') {
          setTimeout(() => {
            try {
              const x = onRejected(this.reason);
              resolvePromise(promise2, x, resolve, reject);
            } catch (error) {
              reject(error);
            }
          }, 0);
        } else {
          this.onResolvedCallbacks.push(() => {
            setTimeout(() => {
              try {
                const x = onResolved(this.value);
                resolvePromise(promise2, x, resolve, reject);
              } catch (error) {
                reject(error);
              }
            }, 0);
          });
  
          this.onRejectedCallbacks.push(() => {
            setTimeout(() => {
              try {
                const x = onRejected(this.reason);
                resolvePromise(promise2, x, resolve, reject);
              } catch (error) {
                reject(error);
              }
            }, 0);
          });
        }
      });
  
      return promise2;
    }
  
    catch(onRejected) {
      return this.then(null, onRejected);
    }
  
    finally(onFinally) {
      return this.then(
        (value) => MyPromise.resolve(onFinally()).then(() => value),
        (reason) => MyPromise.resolve(onFinally()).then(() => { throw reason; })
      );
    }
  }
  
  function resolvePromise(promise, x, resolve, reject) {
    if (promise === x) {
      reject(new TypeError('Chaining cycle detected for promise'));
    }
  
    if (x instanceof MyPromise) {
      x.then(resolve, reject);
    } else {
      resolve(x);
    }
  }
  
  MyPromise.resolve = function (value) {
    return new MyPromise((resolve) => {
      resolve(value);
    });
  };
  
  MyPromise.reject = function (reason) {
    return new MyPromise((_, reject) => {
      reject(reason);
    });
  };
  
  MyPromise.all = function (promises) {
    return new MyPromise((resolve, reject) => {
      const results = [];
      let count = 0;
  
      for (let i = 0; i < promises.length; i++) {
        promises[i].then(
          (value) => {
            results[i] = value;
            count++;
  
            if (count === promises.length) {
              resolve(results);
            }
          },
          (reason) => {
            reject(reason);
          }
        );
      }
    });
  };
  
  MyPromise.race = function (promises) {
    return new MyPromise((resolve, reject) => {
      for (let i = 0; i < promises.length; i++) {
        promises[i].then(
          (value) => {
            resolve(value);
          },
          (reason) => {
            reject(reason);
          }
        );
      }
    });
  };




  let promise = new MyPromise((resolve,reject)=>{
    console.log(1)
    setTimeout(()=>{
        resolve(2);
    },3000);  //class是严格模式,所以这边直接调用是指向undefined
})


promise.then((data)=>{
   console.log(data);
   return new MyPromise((resolve)=>{
      setTimeout(()=>{
          resolve(666)
      },1000)
   })
}).then(console.log)

console.log(3);